import 'package:fig/views/video/video_style.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:orientation/orientation.dart';
import 'package:video_player/video_player.dart';

class VideoProgress extends StatefulWidget {
  final VideoPlayerController controller;
  final bool allowScrubbing;

  final ProgressStyle progressStyle;
  final Function onFullScreenCallback;

  VideoProgress(this.controller, {Key key, this.allowScrubbing = true, this.onFullScreenCallback})
      : this.progressStyle = ProgressStyle(),
        super(key: key);

  @override
  State<StatefulWidget> createState() => _VideoProgressState();
}

class _VideoProgressState extends State<VideoProgress> {
  VoidCallback listener;

  _VideoProgressState() {
    listener = () {
      if (!mounted) {
        return;
      }
      setState(() {});
    };
  }

  bool _isFullScreen = false;

  VideoPlayerController get controller => widget.controller;

  ProgressStyle get progressStyle => widget.progressStyle;

  void onDlanTap() {
    print('onDlanTap TODO:待开发');
  }

  void onFullScreenTap() {
    print('功能不完善，先屏蔽');
    return;
    if (widget.onFullScreenCallback != null) {
      widget.onFullScreenCallback(_isFullScreen);
    }

    setState(() {
      _isFullScreen = !_isFullScreen;
      if (_isFullScreen) {
        // 如果是全屏就切换竖屏
        OrientationPlugin.forceOrientation(DeviceOrientation.portraitUp);
      } else {
        OrientationPlugin.forceOrientation(DeviceOrientation.landscapeRight);
      }
      // _startPlayControlTimer(); // 操作完控件开始计时隐藏
    });
  }

  @override
  void didUpdateWidget(VideoProgress oldWidget) {
    super.didUpdateWidget(oldWidget);
    print('VideoProgress -> didUpdateWidget');
    controller.addListener(listener);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    print('VideoProgress -> didChangeDependencies');
  }

  @override
  void initState() {
    print('VideoProgress -> initState');
    super.initState();
  }

  @override
  void deactivate() {
    print('VideoProgress -> deactivate');
    controller.removeListener(listener);
    super.deactivate();
  }

  @override
  Widget build(BuildContext context) {
    print('VideoProgress -> build');

    return Align(
      alignment: Alignment.bottomCenter,
      child: Container(
        padding: EdgeInsets.only(left: 8, right: 8, bottom: 5),
        child: Flex(
          direction: Axis.horizontal,
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Text(formatDuration(widget.controller.value.position), style: progressStyle.textStyle),
            Expanded(flex: 1, child: _progressBar()),
            Text(formatDuration(widget.controller.value.duration), style: progressStyle.textStyle),
            GestureDetector(child: Padding(padding: EdgeInsets.only(left: 4), child: Icon(Icons.fullscreen, color: progressStyle.fullScreenColor, size: progressStyle.fullScreenSize)), onTap: onFullScreenTap),
            GestureDetector(child: Padding(padding: EdgeInsets.only(left: 6), child: Icon(Icons.airplay, color: progressStyle.dlanColor, size: progressStyle.dlanSize)), onTap: onDlanTap),
          ],
        ),
      ),
    );
  }

  Widget _progressBar() {
    Widget progressIndicator;
    if (controller.value.initialized) {
      final int duration = controller.value.duration.inMilliseconds;
      final int position = controller.value.position.inMilliseconds;

      int maxBuffering = 0;
      for (DurationRange range in controller.value.buffered) {
        final int end = range.end.inMilliseconds;
        if (end > maxBuffering) {
          maxBuffering = end;
        }
      }

      progressIndicator = Stack(
        fit: StackFit.passthrough,
        children: <Widget>[
          LinearProgressIndicator(
            value: maxBuffering / duration,
            valueColor: AlwaysStoppedAnimation<Color>(progressStyle.bufferedColor),
            backgroundColor: progressStyle.backgroundColor,
          ),
          LinearProgressIndicator(
            value: position / duration,
            valueColor: AlwaysStoppedAnimation<Color>(progressStyle.playedColor),
            backgroundColor: Colors.transparent,
          ),
        ],
      );
    } else {
      progressIndicator = LinearProgressIndicator(
        value: null,
        valueColor: AlwaysStoppedAnimation<Color>(progressStyle.playedColor),
        backgroundColor: progressStyle.backgroundColor,
      );
    }

    final Widget paddedProgressIndicator = Padding(
      padding: progressStyle.progressBarPadding,
      child: progressIndicator,
    );

    if (widget.allowScrubbing) {
      return _VideoScrubber(
        child: paddedProgressIndicator,
        controller: controller,
      );
    } else {
      return paddedProgressIndicator;
    }
  }

  String formatDuration(Duration duration) {
    if (duration == null) {
      return '00:00:00';
    }

    int seconds = duration.inSeconds;
    int second = seconds % 60;
    int minute = seconds ~/ 60 % 60;
    int hour = seconds ~/ 3600 % 60;

    return '${timeToString(hour)}:${timeToString(minute)}:${timeToString(second)}';
  }

  String timeToString(int time) {
    if (time < 10) {
      return '0$time';
    }
    return '$time';
  }
}

class _VideoScrubber extends StatefulWidget {
  _VideoScrubber({
    @required this.child,
    @required this.controller,
  });

  final Widget child;
  final VideoPlayerController controller;

  @override
  _VideoScrubberState createState() => _VideoScrubberState();
}

class _VideoScrubberState extends State<_VideoScrubber> {
  bool _controllerWasPlaying = false;

  VideoPlayerController get controller => widget.controller;

  @override
  Widget build(BuildContext context) {
    void seekToRelativePosition(Offset globalPosition) {
      final RenderBox box = context.findRenderObject();
      final Offset tapPos = box.globalToLocal(globalPosition);
      final double relative = tapPos.dx / box.size.width;
      final Duration position = controller.value.duration * relative;
      controller.seekTo(position);
    }

    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      child: widget.child,
      onHorizontalDragStart: (DragStartDetails details) {
        if (!controller.value.initialized) {
          return;
        }
        _controllerWasPlaying = controller.value.isPlaying;
        if (_controllerWasPlaying) {
          controller.pause();
        }
      },
      onHorizontalDragUpdate: (DragUpdateDetails details) {
        if (!controller.value.initialized) {
          return;
        }
        seekToRelativePosition(details.globalPosition);
      },
      onHorizontalDragEnd: (DragEndDetails details) {
        if (_controllerWasPlaying) {
          controller.play();
        }
      },
      onTapDown: (TapDownDetails details) {
        if (!controller.value.initialized) {
          return;
        }
        seekToRelativePosition(details.globalPosition);
      },
    );
  }
}
